package com.tos.second.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tos.second.properties.BaiduAiProperties;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

@Service
public class BaiduAiService {

    @Autowired
    private BaiduAiProperties baiduAiProperties;

    private String accessToken;
    private long tokenExpireTime;
    
    // 支持的图像格式
    private static final Set<String> SUPPORTED_FORMATS = new HashSet<>();
    static {
        SUPPORTED_FORMATS.add("jpg");
        SUPPORTED_FORMATS.add("jpeg");
        SUPPORTED_FORMATS.add("png");
        SUPPORTED_FORMATS.add("bmp");
        SUPPORTED_FORMATS.add("gif");
        SUPPORTED_FORMATS.add("webp");
    }

    /**
     * 获取百度AI Access Token
     */
    public String getAccessToken() throws IOException {
        // 打印调试信息
        System.out.println("百度AI配置信息:");
        System.out.println("API Key: " + baiduAiProperties.getApiKey());
        System.out.println("Secret Key: " + baiduAiProperties.getSecretKey());
        System.out.println("Image Classify URL: " + baiduAiProperties.getImageClassifyUrl());
        System.out.println("Logo Detect URL: " + baiduAiProperties.getLogoDetectUrl());
        System.out.println("Access Token URL: " + baiduAiProperties.getAccessTokenUrl());
        System.out.println("Universal Classify URL: " + baiduAiProperties.getUniversalClassifyUrl());

        // 如果token还未过期，直接返回
        if (accessToken != null && System.currentTimeMillis() < tokenExpireTime) {
            return accessToken;
        }

        // 构造获取token的URL
        String accessTokenUrl = baiduAiProperties.getAccessTokenUrl();
        if (accessTokenUrl == null || accessTokenUrl.isEmpty()) {
            throw new IOException("百度AI Access Token URL未配置");
        }
        
        String url = accessTokenUrl +
                "?grant_type=client_credentials" +
                "&client_id=" + baiduAiProperties.getApiKey() +
                "&client_secret=" + baiduAiProperties.getSecretKey();

        // 发送HTTP请求
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        
        // 确保URL格式正确
        if (httpPost.getURI() == null || httpPost.getURI().getHost() == null) {
            throw new IOException("无效的URL: " + url);
        }

        HttpResponse response = httpClient.execute(httpPost);
        String result = EntityUtils.toString(response.getEntity());

        // 解析JSON响应
        JSONObject jsonObject = JSON.parseObject(result);
        
        // 检查是否有错误
        if (jsonObject.containsKey("error")) {
            String error = jsonObject.getString("error");
            String errorDescription = jsonObject.getString("error_description");
            throw new IOException("获取Access Token失败: " + error + ", " + errorDescription);
        }
        
        accessToken = jsonObject.getString("access_token");

        // 设置过期时间（提前5分钟过期）
        int expiresIn = jsonObject.getIntValue("expires_in");
        tokenExpireTime = System.currentTimeMillis() + (expiresIn - 300) * 1000;

        return accessToken;
    }

    /**
     * Logo识别
     */
    public String logoDetect(MultipartFile imageFile) throws IOException {
        // 1. 验证图像文件
        validateImageFile(imageFile);
        
        // 2. 获取Access Token
        String accessToken = getAccessToken();

        // 3. 构造请求URL
        String logoDetectUrl = baiduAiProperties.getLogoDetectUrl();
        if (logoDetectUrl == null || logoDetectUrl.isEmpty()) {
            throw new IOException("百度AI Logo识别URL未配置");
        }
        
        String url = logoDetectUrl + "?access_token=" + accessToken;

        // 4. 读取图像文件并进行Base64编码
        byte[] imageBytes = imageFile.getBytes();
        String imageBase64 = Base64.getEncoder().encodeToString(imageBytes);

        // 5. 构造请求参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("image", imageBase64));

        // 6. 发送HTTP POST请求
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        
        // 确保URL格式正确
        if (httpPost.getURI() == null || httpPost.getURI().getHost() == null) {
            throw new IOException("无效的URL: " + url);
        }
        
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        HttpResponse response = httpClient.execute(httpPost);
        String result = EntityUtils.toString(response.getEntity());
        
        // 7. 检查响应是否包含错误信息
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.containsKey("error_code")) {
            int errorCode = jsonObject.getIntValue("error_code");
            String errorMsg = jsonObject.getString("error_msg");
            throw new IOException("百度AI识别错误 [" + errorCode + "]: " + errorMsg);
        }

        return result;
    }
    
    /**
     * 通用物体识别
     */
    public String advancedGeneral(MultipartFile imageFile) throws IOException {
        // 1. 验证图像文件
        validateImageFile(imageFile);
        
        // 2. 获取Access Token
        String accessToken = getAccessToken();

        // 3. 构造请求URL
        String imageClassifyUrl = baiduAiProperties.getImageClassifyUrl();
        if (imageClassifyUrl == null || imageClassifyUrl.isEmpty()) {
            throw new IOException("百度AI图像识别URL未配置");
        }
        
        String url = imageClassifyUrl + "?access_token=" + accessToken;

        // 4. 读取图像文件并进行Base64编码
        byte[] imageBytes = imageFile.getBytes();
        String imageBase64 = Base64.getEncoder().encodeToString(imageBytes);

        // 5. 构造请求参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("image", imageBase64));

        // 6. 发送HTTP POST请求
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        
        // 确保URL格式正确
        if (httpPost.getURI() == null || httpPost.getURI().getHost() == null) {
            throw new IOException("无效的URL: " + url);
        }
        
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        HttpResponse response = httpClient.execute(httpPost);
        String result = EntityUtils.toString(response.getEntity());
        
        // 7. 检查响应是否包含错误信息
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.containsKey("error_code")) {
            int errorCode = jsonObject.getIntValue("error_code");
            String errorMsg = jsonObject.getString("error_msg");
            throw new IOException("百度AI识别错误 [" + errorCode + "]: " + errorMsg);
        }

        return result;
    }
    
    /**
     * 看图识万物
     */
    public String universalClassify(MultipartFile imageFile) throws IOException {
        // 1. 验证图像文件
        validateImageFile(imageFile);
        
        // 2. 获取Access Token
        String accessToken = getAccessToken();

        // 3. 构造请求URL
        String universalClassifyUrl = baiduAiProperties.getUniversalClassifyUrl();
        if (universalClassifyUrl == null || universalClassifyUrl.isEmpty()) {
            throw new IOException("百度AI看图识万物URL未配置");
        }
        
        String url = universalClassifyUrl + "?access_token=" + accessToken;

        // 4. 读取图像文件并进行Base64编码
        byte[] imageBytes = imageFile.getBytes();
        String imageBase64 = Base64.getEncoder().encodeToString(imageBytes);

        // 5. 构造请求参数
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("image", imageBase64));
        params.add(new BasicNameValuePair("baike_num", "5")); // 返回百科信息数量
        params.add(new BasicNameValuePair("with_face", "1")); // 检测人物属性
        params.add(new BasicNameValuePair("with_quality", "1")); // 图像质量评估

        // 6. 发送HTTP POST请求
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        
        // 确保URL格式正确
        if (httpPost.getURI() == null || httpPost.getURI().getHost() == null) {
            throw new IOException("无效的URL: " + url);
        }
        
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

        HttpResponse response = httpClient.execute(httpPost);
        String result = EntityUtils.toString(response.getEntity());
        
        // 7. 检查响应是否包含错误信息
        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject.containsKey("error_code")) {
            int errorCode = jsonObject.getIntValue("error_code");
            String errorMsg = jsonObject.getString("error_msg");
            throw new IOException("百度AI识别错误 [" + errorCode + "]: " + errorMsg);
        }

        return result;
    }
    
    /**
     * 验证图像文件格式和内容
     */
    private void validateImageFile(MultipartFile imageFile) throws IOException {
        // 检查文件是否为空
        if (imageFile == null || imageFile.isEmpty()) {
            throw new IOException("图像文件为空");
        }
        
        // 检查文件大小（百度AI限制4MB）
        if (imageFile.getSize() > 4 * 1024 * 1024) {
            throw new IOException("图像文件过大，百度AI要求文件大小不超过4MB");
        }
        
        // 检查文件扩展名
        String originalFilename = imageFile.getOriginalFilename();
        if (originalFilename == null || originalFilename.isEmpty()) {
            throw new IOException("无法获取图像文件名");
        }
        
        String fileExtension = getFileExtension(originalFilename).toLowerCase();
        if (!SUPPORTED_FORMATS.contains(fileExtension)) {
            throw new IOException("不支持的图像格式: " + fileExtension + "，支持的格式: JPG, JPEG, PNG, BMP, GIF, WEBP");
        }
        
        // 尝试读取图像以验证格式
        try {
            BufferedImage image = ImageIO.read(imageFile.getInputStream());
            if (image == null) {
                throw new IOException("无法读取图像文件，可能是损坏的图像或不支持的格式");
            }
        } catch (Exception e) {
            throw new IOException("图像文件格式验证失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.lastIndexOf(".") == -1) {
            return "";
        }
        return filename.substring(filename.lastIndexOf(".") + 1);
    }
}